﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Publishing;

namespace SPHelper
{
	public class Web
	{
		/// <summary>
		/// Get current SPWeb
		/// DO NOT DISPOSE!!!!
		/// </summary>
		/// <returns></returns>
		public static SPWeb GetWeb()
		{
			SPWeb web = null;
			try
			{
				// init
				if (SPContext.Current == null) { throw new Exception("SPContext is null"); }
				if (SPContext.Current.Web == null) { throw new Exception("Failed to get SPWeb from the SPContext object"); }

				web = SPContext.Current.Web;
			}
			catch (Exception ex)
			{
				Log.WriteError("t7kiugdftdrtydruy", ex);
				web = null;
			}
			return web;
		}

		/// <summary>
		/// Get SPWeb from the passed SPSite site collection object and relative url
		/// DO NOT DISPOSE!!!
		/// </summary>
		/// <param name="site"></param>
		/// <param name="url">"/" = root web for current site collection</param>
		/// <returns></returns>
		public static SPWeb GetWeb(SPSite site, string url)
		{
			SPWeb web = null;
			try
			{
				// init
				if (site == null) { site = Site.GetSite(); }
				if (site == null) { throw new Exception("Failed to get SPSite from SPContext"); }
				
				// format url, making it relative
				url = Utilities.ConvertAbsoluteUrlToRelativeUrl(url);

				// open web
				web = site.OpenWeb(url);
				if (web == null) { throw new Exception("Failed to open SPWeb using relative url: " + url); }
			}
			catch (Exception ex)
			{
				Log.WriteError("dyu6fukcgfhygugovhb", ex, "relativeUrl: " + url);
				web = null;
			}
			return web;
		}

		/// <summary>
		/// Get SPWeb from the current site collection, using relative url passed
		/// DO NOT DISPOSE!!!
		/// </summary>
		/// <param name="url">"/" = root web for current site collection</param>
		/// <returns></returns>
		public static SPWeb GetWeb(string url)
		{
			SPWeb web = null;
			try
			{
				web = GetWeb(null, url);
			}
			catch (Exception ex)
			{
				Log.WriteError("67rigfykdffty", ex, "relativeUrl: " + url);
				web = null;
			}
			return web;
		}


		/// <summary>
		/// Get SPWeb reference from Feature's SPFeatureReceiverProperties
		/// DO NOT DISPOSE!!!
		/// </summary>
		/// <param name="properties"></param>
		/// <returns></returns>
		public static SPWeb GetWeb(SPFeatureReceiverProperties properties)
		{
			SPWeb web = null;
			try
			{
				// init
				if (properties == null) { throw new Exception("SPFeatureReceiverProperties passed is null"); }

				try
				{
					web = properties.Feature.Parent as SPWeb;
				}
				catch (Exception ex)
				{
					throw new Exception("Failed to cast SPFeatureReceiverProperties to an SPWeb. Most likely the feature is NOT scoped to Web: " + ex.Message);
				}
			}
			catch (Exception ex)
			{
				Log.WriteError("dt7idt7tfxdfdrdt", ex);
				web = null;
			}
			return web;
		}


		public static SPWeb GetWeb(Guid webId, SPSite site)
		{
			SPWeb web = null;
			try
			{
				// init
				if (webId == null || webId == Guid.Empty) { throw new Exception("Null or empty guid passed for webId"); }
				if (site == null) { site = Site.GetSite(); }
				if (site == null) { throw new Exception("Failed to get SPSite from SPContext"); }


				web = site.AllWebs[webId];
				if (web == null)
				{
					throw new Exception("Failed to find SPWeb in site: " + site.PortalName
						+ " using webId: " + webId);
				}
			}
			catch (Exception ex)
			{
				Log.WriteError("8i67ru6yew54tdsgxd", ex, "webId: " + webId);
				web = null;
			}
			return web;
		}



		/// <summary>
		/// Set Master page template for passed Web
		/// </summary>
		/// <param name="web"></param>
		/// <param name="publishingPagesMasterFilename"></param>
		/// <param name="nonPublishingPagesMasterFilename"></param>
		public static bool SetMaster(SPWeb web, string publishingPagesMasterFilename, string nonPublishingPagesMasterFilename)
		{
			bool isSuccess = false;
			try
			{
				// init
				if (web == null) { throw new Exception("SPWeb passed is null"); }
				if (string.IsNullOrEmpty(publishingPagesMasterFilename) && string.IsNullOrEmpty(nonPublishingPagesMasterFilename)) 
				{ 
					throw new Exception("Publishing master and Non Publishing master cannot both be null"); 
				}


				// create master urls
				Uri publishingPagesMasterUri = null;
				if (!string.IsNullOrEmpty(publishingPagesMasterFilename) && PublishingWeb.IsPublishingWeb(web))
				{
					publishingPagesMasterUri = new Uri(web.Site.Url + "/_catalogs/masterpage/" 
						+ publishingPagesMasterFilename);
				}
				Uri nonPublishingPagesMasterUri = null;
				if (!string.IsNullOrEmpty(nonPublishingPagesMasterFilename))
				{
					nonPublishingPagesMasterUri = new Uri(web.Site.Url + "/_catalogs/masterpage/" 
						+ nonPublishingPagesMasterFilename);
				}

				if (publishingPagesMasterUri != null)
				{
					// master page used by all publishing pages on the site
					web.CustomMasterUrl = publishingPagesMasterUri.AbsolutePath;
				}

				if (nonPublishingPagesMasterUri != null)
				{
					// master page used by all forms and pages on the site NOT publishing pages
					web.MasterUrl = nonPublishingPagesMasterUri.AbsolutePath;
				}
				web.Update();
				isSuccess = true;
			}
			catch (Exception ex)
			{
				Log.WriteError("7i6ro87tje6rhegdsgdfs", ex, "publishing master: " + publishingPagesMasterFilename
					+ ", non publishing master: " + nonPublishingPagesMasterFilename);
				isSuccess = false;
			}
			return isSuccess;
		}

		/// <summary>
		/// Set master page template for passed SPWeb
		/// Applys the template to both publishing and non publishing pagesmas
		/// </summary>
		/// <param name="web"></param>
		/// <param name="masterPageFilename"></param>
		/// <returns></returns>
		public static bool SetMaster(SPWeb web, string masterPageFilename)
		{
			return SetMaster(web, masterPageFilename, masterPageFilename);
		}

		/// <summary>
		/// Get web url, no trailing slash (unless root)
		/// </summary>
		/// <param name="web"></param>
		/// <param name="isAbsoluteUrl"></param>
		/// <returns></returns>
		public static string GetUrl(SPWeb web, bool isAbsoluteUrl)
		{
			string url = null;
			if (web != null)
			{
				// get url from passed SPWeb
				if (!isAbsoluteUrl) { url = web.ServerRelativeUrl; } else { url = web.Url; }

				// remove trailing slash, unless root (which is only a slash)
				if (url != null && url.Length > 1 && url.Substring(url.Length - 1) == "/")
				{
					url = url.Substring(0, url.Length - 1);
				}
			}
			return url;
		}
		/// <summary>
		/// Get relative web url, no trailing slash (unless root)
		/// </summary>
		/// <param name="web"></param>
		/// <returns></returns>
		public static string GetUrl(SPWeb web)
		{
			// call original
			return GetUrl(web, false);
		}




		/// <summary>
		/// Get SPWeb from passed url
		/// parses url, makes relative, removes item, folder, and list information
		/// http://chrisdomino.com/blog/post/A-Nifty-SharePoint-Utility-to-Get-Web-List-and-List-Item-Ids-from-a-URL
		/// </summary>
		public static SPWeb GetWebByUrl(string url, SPSite site)
		{
			SPWeb web = null;
			string originalUrl = url;
			try
			{
				// init
				if (string.IsNullOrEmpty(url)) { throw new Exception("Url passed is null"); }
				if (site == null) { site = SPHelper.Site.GetSite(); }
				if (site == null) { throw new Exception("Failed to get SPSite from SPContext"); }
				string listUrlSegment = null;


				// convert url to absolute url
				if (!Utilities.IsAbsoluteUrl(url)) { url = Utilities.ConvertRelativeUrlToAbsoluteUrl(url, site); }

				// keep parsing out url until we get a valid web
				while (url.IndexOf("/") != -1)
				{
					//get this web by url
					web = site.AllWebs.Where(w => w.Url.Equals(url, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
					if (web != null) { break; }
					else
					{
						// a web was not found - iterate: listName is the part that will be sliced off; url is the new web url to try
						listUrlSegment = url.Substring(url.LastIndexOf("/"));
						url = url.Substring(0, url.LastIndexOf("/"));
					}
				}
			}
			catch (Exception ex)
			{
				SPHelper.Log.WriteError("e658t776564esrdfd", ex, "url: " + originalUrl);
				web = null;
			}
			return web;
		}

		/// <summary>
		/// Get SPWeb by url
		/// </summary>
		/// <param name="url"></param>
		/// <returns></returns>
		public static SPWeb GetWebByUrl(string url)
		{
			// call original
			return GetWebByUrl(url, Site.GetSite());
		}
	}
}
